home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
util
/
smoothzoom.c
< prev
Wrap
C/C++ Source or Header
|
1994-08-01
|
5KB
|
165 lines
/*smoothzoom.c
Eric Pepke
Does a smooth zoom from one eye position and focus distance to another
Usage:
smoothzoom zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel
Example:
smoothzoom 6.0 0 0 -6 2.0 0 1 -2 90 10
starts off with the eye at (0 0 -6) focusing on a point 6 units away and
zooms to the eye at (0 1 -2) focusing on a point 2 units away. It takes
90 frames (3 seconds) to do this and has an acceleration and a deceleration
step of 10 frames apiece.
The zoom distance is the distance from the eye to the focus point, and it
is changed via the perspective control. The eye position is changed by the
perspective control and by moving the space. The best way to get the
numbers is to save to a log while interactively moving. There will be a
begin snapshot/end snapshot block, and a value for LOCATION will be in the
block.
*/
#include <stdio.h>
#include <math.h>
double zoom1, posn1[3];
double zoom2, posn2[3];
void DoFunction(amount, lastAmount)
double amount, lastAmount;
/*Does the function to get to amount (in [0,1]) from lastAmount*/
{
{
printf("set value Perspective\\ Control [%lg 25 0.1 8]\n",
zoom2 * amount + zoom1 * (1.0 - amount));
printf("eyeposn [%lg %lg %lg]\n",
posn2[0] * amount + posn1[0] * (1.0 - amount),
posn2[1] * amount + posn1[1] * (1.0 - amount),
posn2[2] * amount + posn1[2] * (1.0 - amount)
);
printf("snap\n");
}
}
main(argc, argv)
int argc;
char *argv[];
{
double minorStep, amount, lastAmount, check;
long nSteps, nAccel, accelTotal, nInertial, inertialTotal, totalMinorSteps;
long progress;
long k;
if (argc != 11)
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
if (1 != sscanf(argv[1], "%lg", &zoom1))
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
if (1 != sscanf(argv[2], "%lg", &(posn1[0])))
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
if (1 != sscanf(argv[3], "%lg", &(posn1[1])))
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
if (1 != sscanf(argv[4], "%lg", &(posn1[2])))
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
if (1 != sscanf(argv[5], "%lg", &zoom2))
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
if (1 != sscanf(argv[6], "%lg", &(posn2[0])))
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
if (1 != sscanf(argv[7], "%lg", &(posn2[1])))
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
if (1 != sscanf(argv[8], "%lg", &(posn2[2])))
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
if (1 != sscanf(argv[9], "%d", &nSteps))
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
if (1 != sscanf(argv[10], "%d", &nAccel))
{
fprintf(stderr, "usage: %s zoom1 x1 y1 z1 zoom2 x2 y2 z2 nSteps nAccel\n", argv[0]);
exit(-1);
}
/*Calculate the number of time steps in the inertial phase*/
nInertial = nSteps - 2 * nAccel;
if (nInertial < 0)
{
fprintf(stderr, "The total number of steps is not be enough for acceleration.\n");
exit(-1);
}
/*Calculate the number of minor steps in each acceleration phase*/
accelTotal = 0;
for (k = 1; k <= nAccel; ++k)
{
accelTotal += k;
}
/*Calculate the number of minor steps in the inertial phase*/
inertialTotal = nInertial * (nAccel + 1);
/*Calculate the total number of minor steps*/
totalMinorSteps = inertialTotal + 2 * accelTotal;
/*Start off with none done*/
progress = 0;
lastAmount = 0;
/*Do acceleration phase*/
for (k = 1; k <= nAccel; ++k)
{
progress += k;
lastAmount = amount;
amount = ((double) progress) / ((double) totalMinorSteps);
DoFunction(amount, lastAmount);
}
/*Do inertial phase*/
for (k = 0; k < nInertial; ++k)
{
progress += nAccel + 1;
lastAmount = amount;
amount = ((double) progress) / ((double) totalMinorSteps);
DoFunction(amount, lastAmount);
}
/*Do deceleration phase*/
for (k = nAccel; k >= 1; --k)
{
progress += k;
lastAmount = amount;
amount = ((double) progress) / ((double) totalMinorSteps);
DoFunction(amount, lastAmount);
}
}